var ax = (function() {
    'use strict';
    var CID_COOKIE = '__cid__';
    var status = 'ok';
    var handlers = {};
    var raw_handler = undefined;
    var ws;
    var initialized = false;

    function getCookie(name) {
        var value = "; " + document.cookie;
        var parts = value.split("; " + name + "=");
        if (parts.length == 2) return parts.pop().split(";").shift();
    }

    function setCookie(name, value, timeoutSeconds) {
        var date = new Date();
        date.setTime(date.getTime() + timeoutSeconds * 1000);
        var expires = "; expires=" + date.toGMTString();
        document.cookie = name + "=" + value + expires + "; path=/";
    }

    function init(init_handler, error_handler, finish_handler) {
        if (window.MozWebSocket != undefined)
            window.WebSocket = window.MozWebSocket;
        if (window.WebSocket === undefined) {
            console.log('ax error: websockets support is missing in the browser');
            status = 'nowebsockets';
            return;
        }
        var prefix = __state.secure ? 'wss://' : 'ws://';
        var path = prefix + window.location.hostname + ':' +
                   __state.port + '/__ws';
        ws = new WebSocket(path);
        ws.onmessage = function(e) {
            if (raw_handler) {
                if (raw_handler(e.data))
                    return;
            }
            try {
                var msg = JSON.parse(e.data);
                if (msg.type === '__ax_set_cookie') {
                    setCookie('__cid__', __state.cid, __state.conn_timeout);
                    return;
                }
                if (handlers[msg.type] != undefined)
                    handlers[msg.type](msg.data);
                else
                    console.log(
                        'Error: no handler for message "' + msg.type + '"')
            } catch (exn) {
                console.log('onmessage exception: ' + exn.message);
                if (error_handler)
                    error_handler('msgerr', JSON.stringify(exn))
            }
        };
        ws.onclose = function () {
            if (finish_handler)
                finish_handler();
        };
        ws.onopen = function () {
            if (init_handler)
                init_handler();
        };
    }

    return {
        getStatus: function() { return status; },
        init: init,
        on: function(msgtype, handler) {
            handlers[msgtype] = handler;
        },
        onRaw: function(handler) {
            raw_handler = handler;
        },
        send: function(msgtype, data) {
            ws.send(JSON.stringify({'type': msgtype, 'data': data}));
        }
    };

})();
